#region File Description
//-----------------------------------------------------------------------------
// GameplayScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Threading;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using TiledLib;
using darkeggs;

#endregion

namespace GameStateManagement
{
    /// <summary>
    /// This screen implements the actual game logic. It is just a
    /// placeholder to get the idea across: you'll probably want to
    /// put some more interesting gameplay in here!
    /// </summary>
    class GameplayScreen : GameScreen
    {
        #region Fields

        ContentManager content;
        SpriteFont gameFont;
        Map map;
        Texture2D background;
        gogo obj;

        Texture2D bluebug;
        Texture2D redbug;
        Texture2D pinkbug;
        Texture2D greenbug;
        Texture2D cyanbug;
        Texture2D whitebug;
        Texture2D yellowbug;


        Texture2D bluelight;
        Texture2D redlight;
        Texture2D pinklight;
        Texture2D greenlight;
        Texture2D cyanlight;
        Texture2D whitelight;
        Texture2D yellowlight;


        //List<KeyValuePair<string, Texture2D>> lightsTextures = new List<KeyValuePair<string, Texture2D>>();
        //List<KeyValuePair<string, Texture2D>> lasersTextures = new List<KeyValuePair<string, Texture2D>>();
        
        
        List<laser> LASERS = new List<laser>();
        List<light> LIGHTS = new List<light>();

        MouseState mouseStatePrevious;
        MouseState mouseStateCurrent;

        TileLayer tileLayer;

        Texture2D laserTexture;
        Texture2D cursorTex;

        Vector2 mousePos;
        Vector2 mousePosUpdate;

        eggs save;

        Random random = new Random();

        #endregion

        #region Initialization


        /// <summary>
        /// Constructor.
        /// </summary>
        public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(0.1);
            TransitionOffTime = TimeSpan.FromSeconds(0.1);
        }


        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            gameFont = content.Load<SpriteFont>("gamefont");
            map = content.Load<Map>("level1");
            background = content.Load<Texture2D>("bg");
            Texture2D gogoTexture = content.Load<Texture2D>("gogo");
            obj = new gogo(gogoTexture,new Vector2(50,50));
            
            Texture2D eggTexture = content.Load<Texture2D>("eggs");
            save = new eggs(eggTexture,new Vector2(600,700));


            laserTexture = content.Load<Texture2D>("placeholder_laser");
            cursorTex = content.Load<Texture2D>("cursor");
            
            tileLayer = map.GetLayer("walls") as TileLayer;

            // A real game would probably have more content than this sample, so
            // it would take longer to load. We simulate that by delaying for a
            // while, giving you a chance to admire the beautiful loading screen.
            redbug = content.Load<Texture2D>("redbug");
            bluebug = content.Load<Texture2D>("bluebug");
            pinkbug = content.Load<Texture2D>("pinkbug");
            greenbug = content.Load<Texture2D>("greenbug");
            cyanbug = content.Load<Texture2D>("cyanbug");
            whitebug = content.Load<Texture2D>("whitebug");

            LIGHTS.Add(new light(redbug,new Vector2(550,40),"red"));

            Thread.Sleep(1000);

            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            ScreenManager.Game.ResetElapsedTime();
        }


        /// <summary>
        /// Unload graphics content used by the game.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }


        #endregion

        #region Update and Draw


        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
            //update lasers
            for (int i = 0; i < LASERS.Count; i++)
            {
                if (LASERS[i].isAlive())
                    LASERS[i].update();
                else
                    LASERS.Remove(LASERS[i]);
            }
            for (int i = 0; i < LIGHTS.Count; i++)
            {
                if (LIGHTS[i].isAlive())
                {
                    LIGHTS[i].update(tileLayer);
                    Vector2 tempLight = LIGHTS[i].getPos();
                    Vector2 tempEgg = save.getPos();
                    if (Math.Pow(tempEgg.X - tempLight.X, 2) + Math.Pow(tempEgg.Y - tempLight.Y, 2) - Math.Pow(save.getRadius(), 2) <= 0 )
                        save.setHit(10);
                }
                else
                    LIGHTS.Remove(LIGHTS[i]);
            }
            if(save.isDead())
                ExitScreen();



            //update lights

        }


        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;

            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];
            mouseStateCurrent = Mouse.GetState();
            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!

            mousePosUpdate = new Vector2(mouseStateCurrent.X, mouseStateCurrent.Y);
            if (mouseStateCurrent.LeftButton == ButtonState.Pressed && mouseStatePrevious.LeftButton == ButtonState.Released)
            {
                    mousePos = new Vector2(mouseStateCurrent.X, mouseStateCurrent.Y);
                    LASERS.Add(new laser(laserTexture, obj.getArmPosition(), mousePos, "red", 100));
            }


            mouseStatePrevious = mouseStateCurrent;



            if (keyboardState.IsKeyDown(Keys.Left) || keyboardState.IsKeyDown(Keys.Right))
            {

                if (keyboardState.IsKeyDown(Keys.Left))
                {
                    if (keyboardState.IsKeyDown(Keys.Up))
                    {
                        obj.moveGogo(6);
                    }
                    else if (keyboardState.IsKeyDown(Keys.Down))
                    {
                        obj.moveGogo(7);
                    }
                    else
                        obj.moveGogo(3);
                }

                if (keyboardState.IsKeyDown(Keys.Right))
                {
                    if (keyboardState.IsKeyDown(Keys.Up))
                    {
                        obj.moveGogo(5);
                    }

                    else if (keyboardState.IsKeyDown(Keys.Down))
                    {
                        obj.moveGogo(8);
                    }
                    else
                        obj.moveGogo(1);
                }
            }

            else
            {
                if (keyboardState.IsKeyDown(Keys.Up))
                {
                    obj.moveGogo(4);
                }

                if (keyboardState.IsKeyDown(Keys.Down))
                {
                    obj.moveGogo(2);
                }
            }
            if (keyboardState.IsKeyDown(Keys.Escape))
            {
                ExitScreen();//change here
            }

            List<Vector2> tempPositionTile = obj.getPos();
            foreach (Vector2 t in tempPositionTile)
            {
                Point temp = new Point();
                try
                {
                    temp = map.WorldPointToTileIndex(t);
                }
                catch (ArgumentOutOfRangeException e)
                {
                    //
                }
                Tile tile = tileLayer.Tiles[temp.X, temp.Y];
                //System.Diagnostics.Debug.WriteLine(tile.ToString());
                
                if (tile != null)
                {
                    obj.prevPos();
                    break;
                }
            }
        }
      


        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.Black, 0, 0);

            // Our player and enemy are both actually just text strings.
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            spriteBatch.Begin();

            //spriteBatch.DrawString(gameFont, "// TODO", playerPosition, Color.Green);

            //spriteBatch.DrawString(gameFont, "Insert Gameplay Here",
            //                       enemyPosition, Color.DarkRed);
            spriteBatch.Draw(background, new Rectangle(0, 0, 1024, 768), Color.White);
            map.Draw(spriteBatch);
            //Rectangle mouseTemp = new Rectangle
            spriteBatch.Draw(cursorTex,mousePosUpdate,Color.White);
            foreach (laser t in LASERS)
            {
                t.draw(spriteBatch);
            }
            foreach (light t in LIGHTS)
            {
                t.draw(spriteBatch);
            }
            obj.drawTexture(spriteBatch);


            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0)
                ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
        }


        #endregion
    }
}
